/*
 * @Author: swc shanwenchao12138@163.com
 * @Date: 2024-12-24 15:05:33
 * @LastEditors: swc
 * @LastEditTime: 2025-03-17 13:42:00
 * @FilePath: \my\src\components\custom\myFlow\command.ts
 * @Description:
 * @Version: 2.0
 * @Autor: swc
 */
import { ifs, ts, Tsrv } from '@/services';
import { N_oSetupPanel } from '@/types';
import { N_cPflow } from './types';
// eslint-disable-next-line import/order
import { Node } from '@antv/x6';

class T_cmd {
  // 主组件箱
  private compBox: ifs.I_compBox;

  // 主组件ID
  private compID: string;

  // 主组件实例
  private self: any;
  // 主组refs

  // 组件配合 在外部实例化
  private TCoordination: ifs.I_compCoordination;

  private toolbarStatusBak: any = null;

  readonly processData: Map<string, any> = new Map();

  // 主组件created里初始化
  public init(self: any, compBoxInfo: ifs.I_compBoxInfo) {
    this.self = self;
    this.compBox = compBoxInfo.TcompBox;
    this.compID = compBoxInfo.compID;
  }

  public getTcmd(): T_cmd {
    return this;
  }

  // 获取预设节点数据
  public getPresetNodeData() {
    const that = this.self;
    that.presetNodes = [];
    const tableName = 'technology';
    this.getTableData(tableName).then(rows => {
      if (rows && !Tsrv.noValue(rows)) {
        rows.forEach((row: any) => {
          const presetNode: N_cPflow.PresetNode = {
            id: row.id,
            name: row['f_name'],
            data: {
              id: '',
              sequence: 0, // 实际序号会在添加时计算
              processId: row.id,
              processCode: row['process_num'],
              processName: row['f_name'],
              tankData: [],
              paramData: []
            }
          };
          that.presetNodes.push(presetNode);
        });
      }
    });
  }

  // 获取工艺数据
  public getProcessData() {
    this.processData.clear();
    if (this.self.graph) {
      this.self.graph.clearCells();
    }
    const craftID = this.self.craftID;
    if (!craftID) return;
    const tableName = 'process_info';
    const filter = new ts.T_filter();
    filter.filter = { master_bill_id: { $in: [craftID] } };
    this.getTableData(tableName, filter).then(rows => {
      if (rows && !Tsrv.noValue(rows)) {
        // 1、设置节点数据
        // tips：创建节点是图id要与数据rowid同步，this.graph.updateCellId(newNode, '新的雪花ID')
        // 创建节点数据
        this.initGraphNodes(rows);

        // 2、补充节点数据（工艺槽信息、工艺参数信息）
        // 方法：根据所有row的id集合作为条件，获取工艺槽信息、工艺参数信息
        const ids = rows.map((row: any) => row.id);
        const Tfilter = new ts.T_filter();
        Tfilter.filter = { master_bill_id: { $in: ids } };

        // 获取工艺槽信息 process_specified_slot
        const tankTableName = 'process_specified_slot';
        // 获取工艺参数信息 process_para_details
        const paraTableName = 'process_para_details';
        // 3、整理和设置工艺槽信息
        Promise.all([
          this.getTableData(tankTableName, Tfilter),
          this.getTableData(paraTableName, Tfilter)
        ]).then(resp => {
          const tankRows = resp[0];
          const paramsRows = resp[1];
          if (tankRows && !Tsrv.noValue(tankRows)) {
            this.suppNodesData(tankRows, 'tank');
          }
          if (paramsRows && !Tsrv.noValue(paramsRows)) {
            this.suppNodesData(paramsRows, 'param');
          }

          // 4、设置图数据
          this.setGraphNodesData();
        });
      }
    });
  }

  private initGraphNodes(rows: any[]) {
    const that = this.self;
    rows.forEach((row: any) => {
      const sequence = row['m2o|sequential_id|drivi_opera_steps|sequence_num']; // sequential_id
      const node = {
        shape: 'process-node',
        data: {
          id: row.id,
          sequence,
          // processId: row.id,
          processId: row['manuf_operation_id'],
          processCode: row['manuf_operation_num'],
          processName:
            row['process_alias'] ||
            row['m2o|manuf_operation_id|technology|f_name'], // manuf_operation_id
          tankData: [] as N_cPflow.TankData[],
          paramData: [] as N_cPflow.ParamData[]
        } as N_cPflow.ProcessNodeData
      };
      this.processData.set(row.id, node);
    });
  }

  private suppNodesData(rows: any[], type: 'tank' | 'param') {
    rows.forEach((row: any) => {
      const nodeId = row['master_bill_id'];
      const node = this.processData.get(nodeId);
      if (node) {
        if (type === 'tank') {
          node.data.tankData.push({
            id: row.id,
            tankId: row['process_tank_id'],
            tankName: row['m2o|process_tank_id|process_tank|f_name'], // process_tank_id
            // 获取来的数据 没有 “槽编号” 属性数据
            tankNumber: ''
          } as N_cPflow.TankData);
        } else
          node.data.paramData.push({
            id: row.id,
            paramId: row['para_id'],
            paramName: row['m2o|para_id|para_info|title'],
            paramValue: row['parameter_value']
          } as N_cPflow.ParamData);
      } else {
        // console.log('node not found', nodeId);
      }
    });
  }

  private setGraphNodesData() {
    const that = this.self;
    this.processData.forEach((node, nodeId) => {
      const data = node.data as N_cPflow.ProcessNodeData;
      node.position = that.calculateNodePosition(data.sequence);
      node.attrs = {
        sequence: { text: `#${data.sequence}` },
        processName: { text: data?.processName || '未命名工序' },
        processCode: { text: data?.processCode || '无编号' },
        tankIcon: {
          html: `<i class="ivu-icon ivu-icon-md-cube" style="font-size: 16px; color: ${
            data?.tankData?.length ? '#1890ff' : '#999'
          }; cursor: pointer;" data-icon="tank"></i>`
        },
        paramIcon: {
          html: `<i class="ivu-icon ivu-icon-md-settings" style="font-size: 16px; color: ${
            data?.paramData?.length ? '#1890ff' : '#999'
          }; cursor: pointer;" data-icon="param"></i>`
        }
      };
      // const newNode = that.graph.addNode(node);
      // that.graph.updateCellId(newNode, nodeId);
    });

    const sortedNodes = this.sortByProperty(
      Array.from(this.processData.values())
    );
    sortedNodes.forEach((node, index) => {
      const newNode = that.graph.addNode(node);
      const data = node.data as N_cPflow.ProcessNodeData;
      that.graph.updateCellId(newNode, data.id);
    });

    const allNodes = that.graph.getNodes();
    allNodes.forEach((node, index) => {
      const data = node.getData() as N_cPflow.ProcessNodeData;
      const newSequence = data.sequence;
      // 添加连线
      if (index < allNodes.length - 1) {
        that.graph!.addEdge({
          source: node,
          target: allNodes[index + 1],
          connector: 'smooth',
          attrs: {
            line: {
              stroke: '#1890ff',
              strokeWidth: 1
            }
          }
        });
      }
    });
    this.self.currentNodes = allNodes;
  }

  // 排序
  private sortByProperty(nodes: any[]) {
    return nodes.sort((a, b) => {
      // 确保属性存在且是数字类型
      const dataA = a.data as N_cPflow.ProcessNodeData;
      const dataB = b.data as N_cPflow.ProcessNodeData;
      const valueA = Number(dataA.sequence);
      const valueB = Number(dataB.sequence);

      // 比较两个值并返回结果
      if (valueA < valueB) {
        return -1;
      }
      if (valueA > valueB) {
        return 1;
      }
      return 0;
    });
  }

  // 获取行车运行步骤
  public getCarRunSteps() {
    const that = this.self;
    const tableName = 'drivi_opera_steps';
    this.getTableData(tableName).then(rows => {
      if (rows && !Tsrv.noValue(rows)) {
        rows.forEach((row: any) => {
          that.carRunSteps.set(Number(row['sequence_num']), {
            sequenceId: row.id
          });
        });
      }
    });
  }

  // 删除节点操作
  public deleteNode(node: Node): Promise<boolean> {
    const nodeData = node.getData() as N_cPflow.ProcessNodeData;
    const that = this.self;
    return new Promise(resolve => {
      const ctd = new ts.T_ctdArg();
      ctd.setTableName('process_info').setDbType(Tsrv.globalVar.dbType.MYSQL);
      ctd.setRule({} as ifs.I_rule);
      const ids = `"${[nodeData.id].join(`","`)}"`;
      const filter = JSON.parse(`{"id":{"$in":[${ids}]}}`);
      ctd.setDelRecData({} as ifs.I_rule, filter);
      // 加入 ctd操作 前后事件
      // const syncParams = new ts.T_syncParams();
      const p = {
        funName: 'process_info',
        from: '',
        data: { removeRecords: ids },
        parentID: that.craftID
      };
      const syncParams = new ts.T_syncParams();
      const _p = Tsrv.utils.clone(p, true);
      _p.from = 'beforeDelete';
      syncParams
        .setApiName('process_info_bef_delete')
        .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
        .setFunInfo({
          mainFun: '',
          mainFunID: '',
          deputyFunIDs: [],
          deputyFunInfo: [],
          deputyFuns: []
        })
        .setSyncData(_p);
      ctd.setDelRecBefSync([syncParams]);
      Tsrv.batRows(ctd).then(resp => {
        const [b, res, msg] = resp;
        if (b) {
          resolve(true);
        } else {
          msg && that.$msg(msg);
          resolve(false);
        }
      });
    });
  }

  // 获取数据
  public getTableData(tableName: string, filter?: any): Promise<any> {
    const that = this.self;
    return new Promise(resolve => {
      const gpd = new ts.T_getPartDataArg();
      gpd.setFunName(tableName).setLang(that.$i18n.locale || 'en-US');
      gpd.setDbType(Tsrv.globalVar.dbType.MYSQL);
      gpd.setPage(1, 99999);
      gpd.setFilter(filter || {});
      Tsrv.getData<any, ifs.I_getPartDataArg>(gpd)
        .then(([b, res, rows, msg]) => {
          that.loading = false;
          if (!b) {
            msg && that.$msg(msg);
            resolve(false);
          }
          // if (res.data.total > 0) {
          //   resolve(rows);
          // }
          resolve(rows);
        })
        .catch(e => {
          // 正在加载
          that.loading = false;
          console.error(e);
        });
    });
  }

  // 插入数据
  public insertData(
    tableName: string,
    insertRecords: ifs.I_baseData[]
  ): Promise<any> {
    const that = this.self;
    return new Promise(resolve => {
      const ctd = new ts.T_ctdArg();
      ctd
        .setTableName(tableName)
        .setDbType(Tsrv.globalVar.dbType.MYSQL)
        .setRule({} as ifs.I_rule);
      const scope = {};
      // const insertRecords: ifs.I_baseData[] = [];
      // const bData = new ts.T_baseData();
      // bData
      //   .setDataRule({} as ifs.I_rule)
      //   .setFileInfo({})
      //   .setRowData(...(rows as ifs.I_fv[]));
      // insertRecords.push(bData);
      ctd.setInsRecDataMany(scope, ...insertRecords);
      Tsrv.batRows(ctd).then(resp => {
        const [b, res, msg] = resp;
        // msg && that.$msg(msg);
        // msg && Vue.prototype.$msg(msg);
        if (b) {
          resolve(true);
        } else {
          msg && that.$msg(msg);
          resolve(false);
        }
      });
    });
  }

  // 更新数据
  public updateData(
    tableName: string,
    updateRecords: Array<Array<ifs.I_fv>>
  ): Promise<any> {
    const that = this.self;
    return new Promise(resolve => {
      const ctd = new ts.T_ctdArg();
      ctd.setTableName(tableName).setDbType(Tsrv.globalVar.dbType.MYSQL);
      ctd.setRule({} as ifs.I_rule);
      let filter: any = {};
      const ctdUpdDatas: ifs.I_ctdUpdData[] = [];
      updateRecords.forEach(ele => {
        const ctdUpdData = new ts.T_ctdUpdData();
        ctdUpdData.setDataRule({} as ifs.I_rule).setFileInfo({});
        const rowData: ifs.I_fv[] = [];
        ele.forEach(item => {
          // 取出id作为过滤条件
          if (item?.field === 'id') {
            filter = { id: item?.value };
          } else {
            rowData.push(item);
          }
        });
        ctdUpdData.setFilter(filter);
        ctdUpdData.setRowData(...rowData);
        ctdUpdDatas.push(ctdUpdData);
      });
      ctd.setUpdRecDataMany(...ctdUpdDatas);
      Tsrv.batRows(ctd).then(resp => {
        const [b, res, msg] = resp;
        if (b) {
          resolve(true);
        } else {
          msg && that.$msg(msg);
          resolve(false);
        }
      });
    });
  }

  // 删除数据
  public deleteData(tableName: string, removeRecords: string[]): Promise<any> {
    const that = this.self;
    return new Promise(resolve => {
      const ctd = new ts.T_ctdArg();
      ctd.setTableName(tableName).setDbType(Tsrv.globalVar.dbType.MYSQL);
      ctd.setRule({} as ifs.I_rule);
      const ids = `"${removeRecords.join(`","`)}"`;
      const filter = JSON.parse(`{"id":{"$in":[${ids}]}}`);
      ctd.setDelRecData({} as ifs.I_rule, filter);
      Tsrv.batRows(ctd).then(resp => {
        const [b, res, msg] = resp;
        if (b) {
          resolve(true);
        } else {
          msg && that.$msg(msg);
          resolve(false);
        }
      });
    });
  }

  // 构建组件协作处理类
  public newTcompCoordination(conf: any) {
    // 组件调度
    this.TCoordination = new ts.T_compCoordination(
      conf.name,
      conf.messageConfig,
      {
        setTempToolbarStatusDisabled: (
          p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
        ) => {
          this.setTempToolbarStatusDisabled(p);
        },
        setTempToolbarStatusUnDisabled: (
          p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
        ) => {
          this.setTempToolbarStatusUnDisabled(p);
        },
        cleanSubCompData: (
          p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
        ) => {
          // 通知组件清空
          this.self.cleanSubCompData(p);
        },
        setMask: (p: boolean) => {
          this.self.isMask = p;
        }
      }
    );
  }

  // 处理组件协调
  public receEventCoordination(
    m: N_oSetupPanel.N_comps.I_eventCoordinationMsg
  ) {
    this.TCoordination.receEventCoordination(m)
      .then(([b, msg]) => {})
      .catch(msg => {
        console.error(msg);
        // this.self.$msg(msg);
      });
  }

  private setTempToolbarStatusDisabled(
    p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) {
    if (Tsrv.utils.noValue(this.toolbarStatusBak)) {
      this.toolbarStatusBak = Tsrv.utils.clone(this.self.toolbarList, true);
      if (!Tsrv.noValue(this.self.toolbarList)) {
        this.self.toolbarList.forEach(el => {
          el.disabled = true;
        });
      }
    }
  }

  private setTempToolbarStatusUnDisabled(
    p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) {
    if (!Tsrv.utils.noValue(this.toolbarStatusBak)) {
      this.toolbarStatusBak.forEach(e => {
        if (!Tsrv.noValue(this.self.toolbarList)) {
          this.self.toolbarList.forEach(el => {
            if (e.key === el.key) el.disabled = e.disabled;
          });
        }
      });

      this.toolbarStatusBak = null;
    }
  }

  // 处理组件协调
  public sendEventCoordination(
    type: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) {
    const r = this.TCoordination.sendEventCoordination(type, this.self.$bus)
      .then(([b, msg]) => {})
      .catch(msg => {
        console.error(msg);
        // this.self.$msg(msg);
      });
  }
}
interface I_cmd extends T_cmd {}
export { I_cmd, T_cmd };
